using System;

namespace MyFramework.Singleton
{
    /// <summary>
    /// 普通单例模式
    /// </summary>
    public abstract class Singleton<T> where T : Singleton<T>, new()
    {
        private static T _instance;

        protected Singleton()
        {
            // 抛异常防止外部直接使用 new()创建实例
            if (_instance != null)
            {
                throw new InvalidOperationException("不能直接实例化单例类，请使用GetInstance()方法获取实例。");
            }
        }

        public static T GetInstance()
        {
            return _instance ??= new T();
        }
    }

    /// <summary>
    /// 避免泛型类型中存在 static 字段,提到基类,所有的线程安全单例用同一个锁对象
    /// </summary>
    public abstract class SingletonLock
    {
        protected static readonly object LockObject = new();
    }

    /// <summary>
    /// 线程安全的单例模式
    /// </summary>
    public abstract class SingletonThreadSafe<T> : SingletonLock where T : class
    {
        private static T _instance;

        public static T GetInstance()
        {
            // 双重检查锁定
            // 第一次检查，避免不必要的锁
            if (_instance == null)
            {
                // 使用基类中的静态锁
                lock (LockObject)
                {
                    // 第二次检查，确保只创建一个实例
                    _instance ??= Activator.CreateInstance<T>();
                }
            }

            return _instance;
        }
    }
}